﻿namespace Simple.Services;

public class OrganizationService
{
    private readonly SimpleDbContext _context;
    private readonly ICurrentUserService _currentUserService;
    private readonly ISimpleService _simpleService;

    public OrganizationService(SimpleDbContext context, ICurrentUserService currentUserService, ISimpleService simpleService)
    {
        _context = context;
        _currentUserService = currentUserService;
        _simpleService = simpleService;
    }

    public async Task<List<OrganizationModel>> GetAsync()
    {
        var organizations = await _context.Set<SysOrganization>().ToListAsync();
        return MapperHelper.Map<List<OrganizationModel>>(organizations);
    }

    public async Task<List<SysOrganization>> GetEntitysAsync()
    {
        return await _context.Set<SysOrganization>().ToListAsync();
    }

    public async Task<PageResultModel<OrganizationModel>> GetPageAsync(OrganizationPageInputModel input)
    {
        var result = new PageResultModel<OrganizationModel>();
        var query = _context.Set<SysOrganization>().AsQueryable();

        // 超级管理员直接获取所有数据
        if (!_currentUserService.IsSuperAdmin)
        {
            var orgList = await GetEntitysAsync();
            var userOrgEntity = GetParentOrganization(orgList, _currentUserService.OriginalOrgId);
            var orgIds = new List<Guid>();
            // 如果当前登录的机构隶属于用户自身所在部门，那就查询用户自身部门和其子部门下的数据
            if (userOrgEntity?.Id == _currentUserService.OrganizationId)
            {
                orgIds = GetChildrenOrganization(orgList, _currentUserService.OriginalOrgId);
            }
            // 如果登录的机构不属于自身所在部门，那就说明是通过数据授权得到的机构权限，只能查询授权部门的数据（不包含子部门）
            var dataScope = await _simpleService.GetService<UserService>().GetUserDataScopeAsync();
            if (dataScope != null && dataScope.UserDataScopes.Any())
            {
                var curAllOrgs = GetChildrenOrganization(orgList, _currentUserService.OrganizationId);
                var curOrgIds = curAllOrgs.Where(s => dataScope.UserDataScopes.Exists(d => d.OrganizationId == s)).ToList();
                orgIds.AddRange(curOrgIds);
            }

            if (orgIds.Any())
            {
                orgIds = orgIds.Distinct().ToList();
                if (orgIds.Count == 1)// 命中索引
                    query = query.Where(s => orgIds[0] == s.Id);
                else
                    query = query.Where(s => orgIds.Contains(s.Id));
            }
        }


        // 根据条件查询
        if (input.Pid.HasValue)
        {
            query = query.Where(o => o.Id == input.Pid || o.ParentId == input.Pid);
        }
        if (!string.IsNullOrEmpty(input.Name))
        {
            // AND ((@__input_Name_0 LIKE N'') OR (CHARINDEX(@__input_Name_0, [s].[Name]) > 0))
            //query = query.Where(o => o.Name.Contains(input.Name));

            // AND ([s].[Name] LIKE @__Format_1)
            query = query.Where(o => EF.Functions.Like(o.Name, $"%{input.Name}%"));
        }

        // 获取总数量
        result.TotalRows = await query.CountAsync();

        // 分页查询
        query = query.OrderBy(o => o.Sort).Page(input.PageNo, input.PageSize);
        var organizations = await query.ToListAsync();
        result.Rows = MapperHelper.Map<List<OrganizationModel>>(organizations);

        result.SetPage(input);
        result.CountTotalPage();

        return result;
    }

    public async Task<List<AntTreeNode>> GetTreeAsync()
    {
        var query = _context.Set<SysOrganization>().AsQueryable();
        // 超级管理员直接获取所有数据
        if (!_currentUserService.IsSuperAdmin)
        {
            var orgList = await GetEntitysAsync();
            var userOrgEntity = GetParentOrganization(orgList, _currentUserService.OriginalOrgId);
            var orgIds = new List<Guid>();
            // 如果当前登录的机构隶属于用户自身所在部门，那就查询用户自身部门和其子部门下的数据
            if (userOrgEntity?.Id == _currentUserService.OrganizationId)
            {
                orgIds = GetChildrenOrganization(orgList, _currentUserService.OriginalOrgId);
            }
            // 如果登录的机构不属于自身所在部门，那就说明是通过数据授权得到的机构权限，只能查询授权部门的数据（不包含子部门）
            var dataScope = await _simpleService.GetService<UserService>().GetUserDataScopeAsync();
            if (dataScope != null && dataScope.UserDataScopes.Any())
            {
                var curAllOrgs = GetChildrenOrganization(orgList, _currentUserService.OrganizationId);
                var curOrgIds = curAllOrgs.Where(s => dataScope.UserDataScopes.Exists(d => d.OrganizationId == s)).ToList();
                orgIds.AddRange(curOrgIds);
            }

            if (orgIds.Any())
            {
                orgIds = orgIds.Distinct().ToList();
                if (orgIds.Count == 1)// 命中索引
                    query = query.Where(s => orgIds[0] == s.Id);
                else
                    query = query.Where(s => orgIds.Contains(s.Id));
            }
        }
        var organizations = await query.ToListAsync();
        List<TreeNode> nodes = MapperHelper.Map<List<TreeNode>>(organizations);

        var builder = AntTreeNode.CreateBuilder(nodes);
        return builder.Build();
    }

    public async Task<int> AddAsync(OrganizationModel model)
    {
        if (await _context.Set<SysOrganization>().AnyAsync(o => o.Code == model.Code))
        {
            throw AppResultException.Status409Conflict("存在相同编码的组织");
        }

        var organization = MapperHelper.Map<SysOrganization>(model);
        await _context.AddAsync(organization);
        return await _context.SaveChangesAsync();
    }

    public async Task<int> UpdateAsync(OrganizationModel model)
    {
        if (await _context.Set<SysOrganization>().AnyAsync(o => o.Id != model.Id && o.Code == model.Code))
        {
            throw AppResultException.Status409Conflict("存在相同编码的组织");
        }

        var organization = await _context.Set<SysOrganization>()
            .Where(o => model.Id == o.Id)
            .FirstOrDefaultAsync();

        if (organization == null)
        {
            throw AppResultException.Status404NotFound("找不到组织，更新失败");
        }

        MapperHelper.Map<OrganizationModel, SysOrganization>(model, organization);
        _context.Update(organization);
        int ret = await _context.SaveChangesAsync();

        if (ret == 0)
        {
            throw AppResultException.Status200OK("更新记录数为0");
        }

        return ret;
    }

    public async Task<int> DeleteAsync(IEnumerable<Guid> ids) // List<Guid> ids
    {
        var organizations = await _context.Set<SysOrganization>()
            .Where(o => ids.Contains(o.Id))
            .ToListAsync();

        _context.RemoveRange(organizations);
        return await _context.SaveChangesAsync();
    }

    public async Task<List<OrganizationModel>> GetPrimaryOrganization(bool? isAdmin = null, Guid? userId = null)
    {
        isAdmin = isAdmin ?? _currentUserService.IsSuperAdmin;
        userId = userId ?? _currentUserService.UserId;
        var result = new List<OrganizationModel>();
        // 首先获取当前用户所在组织机构
        var orgList = _context.Set<SysOrganization>().ToList();
        if(isAdmin.Value)
        {
            var primaryOrgs = orgList.Where(s => s.ParentId == default(Guid)).ToList();
            return MapperHelper.Map<List<SysOrganization>, List<OrganizationModel>>(primaryOrgs);
        }
        var curUser = await _context.Set<SysUser>().Where(s => s.Id == userId).FirstOrDefaultAsync();
        if (curUser != null)
        {
            var organization = GetParentOrganization(orgList, curUser.OrganizationId.Value);
            if (organization != null)
            {
                var model = MapperHelper.Map<SysOrganization, OrganizationModel>(organization);
                result.Add(model);
            }
        }

        // 获取授权的部门
        var userDataScopes =  _context.Set<SysUserDataScope>().Where(s => s.UserId == userId).ToList();
        if (userDataScopes != null && userDataScopes.Any())
        {
            foreach (var scope in userDataScopes)
            {
                var organization = GetParentOrganization(orgList, scope.OrganizationId);
                if (organization != null && !result.Any(s => s.Id == organization.Id))
                {
                    var model = MapperHelper.Map<SysOrganization, OrganizationModel>(organization);
                    result.Add(model);
                }
            }
        }
        return result;
    }

    public SysOrganization GetParentOrganization(List<SysOrganization> organizations, Guid childrenId)
    {
        var organization = organizations.FirstOrDefault(s => s.Id == childrenId);
        if (organization.ParentId == default(Guid))
        {
            return organization;
        }
        else
        {
            return GetParentOrganization(organizations, organization.ParentId);
        }
    }

    public List<Guid> GetChildrenOrganization(List<SysOrganization> organizations, Guid parentId)
    {
        if (organizations == null)
        {
            organizations = _context.Set<SysOrganization>().ToList();
        }
        var ids = new List<Guid>();
        ids.Add(parentId);
        var childrenOrgs = organizations.Where(s => s.ParentId == parentId).ToList();
        if (childrenOrgs != null && childrenOrgs.Any())
        {
            foreach (var children in childrenOrgs)
            {
                ids.AddRange(GetChildrenOrganization(organizations, children.Id));
            }
        }
        return ids;
    }
}
